﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S3.DataModel;
using S3.Common;

namespace S3.Biz
{
    public class GoodsStoreManager : CommonManager
    {
        #region constants

        private static readonly string Ready = ItemStatusValue.Text[ItemStatus.Avaiable];

        #endregion

        #region Delete All

        /// <summary>
        /// Xoa tat ca ban ghi
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>        
        public IEnumerable<GoodsStore> DeleteAll()
        {
            try
            {
                var list = _entities.GoodsStores.ToList();

                if (list != null)
                {
                    list.ForEach(_entities.DeleteObject);

                    _entities.SaveChanges();
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::DeleteAll::", ex, true);
                }
            }

            return null;
        }
        #endregion

        #region GetAllAvaiable

        /// <summary>
        /// Load tat ca ban ghi dang o trang thai san hang
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>        
        public IEnumerable<GoodsStore> GetAllAvaiable()
        {
            try
            {

                var list = _entities.GoodsStores.Where(a => a.Status == Ready);

                if (list != null)
                {
                    return list.OrderBy(x => x.ItemName);
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::GetAllAvaiable::", ex, true);
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// Load tat ca ban ghi
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        #region GetAll
        public IQueryable<GoodsStore> GetAll()
        {
            try
            {
                return _entities.GoodsStores.OrderBy(i => i.ItemName);

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::GetAll::", ex, true);
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// Get one item
        /// </summary>
        /// <param name="itemId"></param>
        /// <returns></returns>
        #region Get One Item
        public GoodsStore GetOne(long itemId)
        {
            try
            {
                return _entities.GoodsStores.Where(i => i.ItemID == itemId).FirstOrDefault();

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::GetOne::", ex, true);
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// Thuc hien dieu chinh so luong hang ban vao trong kho. Neu het hang tu dong chuyen trang thai
        /// Dieu kien xuat hang (isImport = false): so luong > 0 va hang co trang thai san sang de ban.
        /// </summary>
        /// <param name="itemId">Ma so hang hoa</param>
        /// <param name="qtyOnHand">so luong hang can ban hoac can nhap vao kho.</param>
        /// <param name="isImport">Co phai dang nhap hang khong?</param>
        /// <param name="qtyAdjusted">So luong hang hoa da dieu chinh</param>
        /// <returns></returns>       
        public int AdjustItemQuantity(long itemId, decimal qtyOnHand, bool isImport, ref decimal qtyAdjusted)
        {
            try
            {
                var item = GetOne(itemId);
                if (item != null) //Neu ton tai ban ghi
                {
                    string MsgNote = "";
                    if (isImport)//Neu la dang nhap hang hoa => viec dieu chinh la them so luong hang.
                    {
                        item.QtyInStock = item.QtyInStock.Value + qtyOnHand;
                        qtyAdjusted = qtyOnHand;
                        MsgNote = Constants.MsgAddedGoodsQuantity;
                    }
                    else//Nguoc lai la xuat hang hoa. Chi xuat voi so luong hien co trong kho
                    {
                        if (item.QtyInStock > 0)// && item.Status == ItemStatusValue.Text[ItemStatus.Avaiable]; Neu so luong trong kho > 0 va hang trong trang thai san sang de ban
                        {
                            //Neu so luong hang hoa trong kho nhieu hon so luong can ban => tru di so luong ban.
                            if (item.QtyInStock.Value > qtyOnHand)
                            {
                                item.QtyInStock = item.QtyInStock.Value - qtyOnHand;
                                qtyAdjusted = qtyOnHand;
                            }
                            else//Neu so luong hang trong kho it hon so luong can ban => ban het so luong trong kho.
                            {
                                qtyAdjusted = qtyOnHand - item.QtyInStock.Value;
                                item.QtyInStock = 0;
                                item.Status = ItemStatusValue.Text[ItemStatus.Empty];//Chuyen sang trang thai het hang.
                            }

                            MsgNote = Constants.MsgSubtractGoodsQuantity;
                        }
                    }

                    //Notes
                    string[] param = { qtyAdjusted.ToString() };
                    if (MsgNote.Equals(Constants.MsgSubtractGoodsQuantity))
                    {
                        item.Note += Utils.FormatNotesMessage(param, NotesType.SubtractGoods);
                    }
                    else if (MsgNote.Equals(Constants.MsgAddedGoodsQuantity))
                    {
                        item.Note += Utils.FormatNotesMessage(param, NotesType.AddedGoods);
                    }

                    item.ModifiedBy = Common.Constants.StaffName;
                    item.ModifiedDate = DateTime.Now;

                    return _entities.SaveChanges();
                }
                else
                {
                    qtyAdjusted = 0;
                }

            }
            catch (Exception ex)
            {
                qtyAdjusted = 0;
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::AdjustItemQuantity::", ex, true);
                }
            }

            return 0;
        }

        public int Save(GoodsStore input)
        {
            try
            {
                GoodsStore entry = null;

                if (IsExist(ref entry))
                {
                    entry.LotNo = input.LotNo;

                    entry.ItemName = input.ItemName;

                    entry.UnitPrice = input.UnitPrice;
                    entry.UnitType = input.UnitType;
                    entry.TaxType = input.TaxType;
                    entry.TaxPercent = input.TaxPercent;
                    entry.TaxAmount = input.TaxAmount;
                    entry.ImportDate = input.ImportDate;
                    entry.ModifiedDate = DateTime.Now;
                    entry.ModifiedBy = Common.Constants.StaffName;
                    entry.Status = input.Status;
                    entry.ImportUnitPrice = input.ImportUnitPrice;
                    entry.QtyInStock = input.QtyInStock;
                    entry.BarCode = input.BarCode;
                    entry.ExpireDate = input.ExpireDate;
                    entry.CategoryName = input.CategoryName;
                    entry.SubCategoryName = input.SubCategoryName;
                    entry.IsQuickAdd = input.IsQuickAdd;
                    entry.Note = input.Note;

                }
                else
                {
                    //Add new
                    input.ModifiedBy = Common.Constants.StaffName;
                    input.ModifiedDate = DateTime.Now;
                    input.Status = ItemStatusValue.Text[ItemStatus.Avaiable];

                    //if (item.AdditionalItemID == 0)
                    //{
                    _entities.AddToGoodsStores(input);
                    //}
                }


                //Submit change
                return _entities.SaveChanges();
                //ActionLogger.LogAction(ActionType.ChangeService, Constants.StaffName, DateTime.Now, new string[] { });

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::Save::", ex, true);
                }
            }

            return 0;

        }

        /// <summary>
        /// Xoa tat ca hang hoa trong kho va tao moi tu dau.
        /// </summary>
        /// <param name="input"></param>
        public void SaveAll(List<GoodsStore> inputList)
        {
            try
            {
                //Delete all old items
                var oldList = GetAll().ToList();
                oldList.ForEach(_entities.DeleteObject);
                _entities.SaveChanges();

                if (inputList != null && inputList.Count > 0)
                {
                    foreach (var item in inputList)
                    {
                        //Check exist first
                        // If existing then update else add new
                        //var entry = item;

                        //if (IsExist(ref entry))
                        //{
                        //    entry.UnitPrice = item.UnitPrice;
                        //    entry.Status = item.Status;
                        //    entry.ModifiedBy = common.Constants.StaffName;
                        //    entry.ModifiedDate = DateTime.Now;
                        //}
                        //else
                        //{
                        //Add new
                        item.ModifiedBy = Common.Constants.StaffName;
                        item.ModifiedDate = DateTime.Now;
                        //item.Status = AdditionalItemStatusValue.Text[AddditonalItemStatus.Avaiable];

                        //if (item.AdditionalItemID == 0)
                        //{
                        _entities.AddToGoodsStores(item);
                        //}
                        //}
                    }

                    //Submit change
                    _entities.SaveChanges();
                    //ActionLogger.LogAction(ActionType.ChangeService, Constants.StaffName, DateTime.Now, new string[] { });

                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::SaveAll::", ex, true);
                }
            }

        }

        /// <summary>
        /// Check existing or not
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public bool IsExist(ref GoodsStore input)
        {
            //Check parameter
            if (input == null) return false;

            var itemName = input.ItemName;

            try
            {
                var output = _entities.GoodsStores.Where(a => a.ItemName.ToLower() == itemName.ToLower());
                return output != null && output.Count() > 0 ? true : false;
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("GoodsStoreManager::IsExist::" + input.ItemName, ex, true);
                }
            }

            return false;
        }
    }
}
